package com.riekoff.particlecubeworld.editor.zonierung;

import java.util.ArrayList;
import java.util.List;

import com.riekoff.particlecubeworld.editor.AControllableColorMap;
import com.riekoff.particlecubeworld.editor.APatternTextureRenderer;
import com.riekoff.particlecubeworld.editor.ATilePattern;
import com.riekoff.particlecubeworld.editor.zonierung.ADirectEditZonierung;

import cc.creativecomputing.CCApp;
import cc.creativecomputing.CCApplicationManager;
import cc.creativecomputing.control.CCControl;
import cc.creativecomputing.events.CCKeyEvent;
import cc.creativecomputing.graphics.CCColor;
import cc.creativecomputing.graphics.CCDrawMode;
import cc.creativecomputing.graphics.shader.CCGLSLShader;
import cc.creativecomputing.graphics.texture.CCTexture.CCTextureTarget;
import cc.creativecomputing.graphics.texture.CCTexture2D;
import cc.creativecomputing.graphics.texture.CCTextureData;
import cc.creativecomputing.graphics.texture.CCTextureIO;
import cc.creativecomputing.io.CCIOUtil;
import cc.creativecomputing.math.CCMath;

public class AZonierungEditor extends CCApp {
	
	@CCControl(name = "tile raster size", min = 0.001f, max = 1f)
	private float _cTileRasterWidth = 0.1f;
	
	@CCControl(name = "motar thickness", min = 0.0001f, max = 1f)
	private float _cMotarThickness = 0.01f;
	
	@CCControl(name = "motar hue", min = 0, max = 1)
	private float motarHue = 0;
	
	@CCControl(name = "motar saturation", min = 0, max = 1)
	private float motarSaturation = 0;
	
	@CCControl(name = "motar brightness", min = 0, max = 1)
	private float motarBrightness = 0;
	
	@CCControl(name = "pattern index 0", min = 0, max = 10)
	private int _cPattern0 = 0;
	
	@CCControl(name = "pattern scale 0", min = 1, max = 10)
	private int _cPatternScale0 = 0;
	
	@CCControl(name = "pattern index 1", min = 0, max = 10)
	private int _cPattern1 = 0;

	
	private CCGLSLShader _myShader;
	
	private int[] _myZones = new int[100];
	
	private List<ATilePattern> _myPatterns = new ArrayList<>();
	private ATilePattern _myPattern0 = null;

	private AControllableColorMap _myColorMap0;
	
	private ADirectEditZonierung _myZones0 = new ADirectEditZonierung(null);
	
	private CCTexture2D _myRandomTexture;

	@Override
	public void setup() {
		addControls("app", "app", this);
		
		for(String myFile : CCIOUtil.list("pattern", "txt")){
			_myPatterns.add(new ATilePattern("pattern/" + myFile, g));
		}
		if(_cPattern0 < _myPatterns.size())_myPattern0 = _myPatterns.get(_cPattern0);
		
		_myShader = new CCGLSLShader(
			CCIOUtil.classPath(APatternTextureRenderer.class, "tex_brick_vertex.glsl"),
			CCIOUtil.classPath(APatternTextureRenderer.class, "tex_brick_fragment.glsl")
		);
		_myShader.load();
		
		addControls("zonierung", "zonierung 0", 1, _myZones0);
		
		_myColorMap0 = new AControllableColorMap(CCTextureIO.newTextureData("colorschemekompakt.png"));
		addControls("farb palette 0", "color map", 0, _myColorMap0);
		
		for(int i = 0; i < _myZones.length;i++){
			_myZones[i] = (int)CCMath.random(5);
		}
		
		CCTextureData myRandom = new CCTextureData(200,200);
		for(int x = 0; x < myRandom.width(); x++ ){
			for(int y = 0; y < myRandom.height(); y++ ){
				myRandom.setPixel(x, y, new CCColor(CCMath.random(),CCMath.random(),CCMath.random()));
			}
		}
		_myRandomTexture = new CCTexture2D(myRandom, CCTextureTarget.TEXTURE_RECT);
	}
	
	private boolean _myDoUpdate = false;

	@Override
	public void update(final float theDeltaTime) {
		if(frameCount % 10 == 0){
			_myColorMap0.update(theDeltaTime);
			if(_cPattern0 < _myPatterns.size()){
				_myPattern0 = _myPatterns.get(_cPattern0);
				_myZones0.pattern(_myPattern0);
			}
		}
	
	}
	
	@Override
	public void keyPressed(CCKeyEvent theKeyEvent) {
		switch(theKeyEvent.keyCode()){
		case VK_Z:
			for(int i = 0; i < _myZones.length;i++){
				_myZones[i] = (int)CCMath.random(5);
			}
			break;
		case VK_C:
//			_myColorMap0.randomize(1);
			break;
		case VK_U:
			_myDoUpdate = true;
			break;
		}
	}
	

	@Override
	public void draw() {
		g.clear();
		
		if(_myPattern0 == null)return;
		
		g.color(255);
		_myShader.start();
		g.texture(0,_myPattern0.pattern());
		g.texture(1,_myColorMap0.texture());
		g.texture(2, _myZones0.zoneTexture());
		
		g.texture(7,_myRandomTexture);
		float tileMotarWidth = 1;
		float motarStep = _cMotarThickness;
		
		_myShader.uniform1f("tileMotarWidth", tileMotarWidth);
		_myShader.uniform1f("motarStep", motarStep);
		
		_myShader.uniform4f("motarColor", CCColor.createFromHSB(motarHue, motarSaturation, motarBrightness));
		
		_myShader.uniform1i("pattern", 0);
		_myShader.uniform1i("colorMap0", 1);
		_myShader.uniform1i("zones0", 2);
		_myShader.uniform1f("patternScale", _cPatternScale0 * _cTileRasterWidth);
		

		_myShader.uniform1i("colorMap1", 4);
		_myShader.uniform1i("zones1", 5);
		

		_myShader.uniform1i("random", 7);
		
		_myShader.uniform1f("colorBlend", 0f);
		_myShader.uniform1f("colorBlendRange", 0f);
		_myShader.uniform("colorReverse", false);
			
		_myShader.uniform1f("colorXOffset", 0f);
		_myShader.uniform1f("colorYOffset", 0f);
		_myShader.uniform1f("colorRandomOffset", 0f);
		
		_myShader.uniform2f("patternDimension", _myPattern0.width, _myPattern0.height);
		_myShader.uniform2f("patternPosition", 0, 0);
		
		_myShader.uniform1f("zoneBlend", 0f);
		_myShader.uniform1f("zoneBlendRange", 0f);
		_myShader.uniform("zoneReverse", false);
			
		_myShader.uniform1f("zoneXOffset", 0f);
		_myShader.uniform1f("zoneYOffset", 0f);
		_myShader.uniform1f("zoneRandomOffset", 0f);
		
		
		float aspect = (float)height / width;
		
		g.beginShape(CCDrawMode.QUADS);
		g.textureCoords(0, 0, 0);
		g.vertex(-width/2, -height/2);
		g.textureCoords(0, 1, 0);
		g.vertex( width/2, -height/2);
		g.textureCoords(0, 1, aspect);
		g.vertex( width/2,  height/2);
		g.textureCoords(0, 0, aspect);
		g.vertex(-width/2,  height/2);
		g.endShape();
		g.noTexture();
		_myShader.end();
		
		g.color(255);
		g.image(_myZones0.zoneTexture(), 0,0,200,200);
		
//		g.noBlend();
//		g.beginShape(CCDrawMode.QUADS);
//		for(int y = 0; y < _myPattern.height; y++){
//			for(int x = 0; x < _myPattern.width; x++){
//				g.color(_myPattern.tileindices[x][y] / 15f);
//				g.vertex(x * _cSpace,y  * _cSpace);
//				g.vertex((x + 1) * _cSpace,y  * _cSpace);
//				g.vertex((x + 1) * _cSpace,(y + 1)  * _cSpace);
//				g.vertex(x * _cSpace,(y + 1)  * _cSpace);
//				
//			}
//		}
//		g.endShape();
	}

	public static void main(String[] args) {
		CCApplicationManager myManager = new CCApplicationManager(AZonierungEditor.class);
		myManager.settings().size(1500, 1100);
		myManager.start();
	}
}
